package br.gov.ibama.client.visao.funcionario;

import java.util.ArrayList;
import java.util.List;

import br.gov.ibama.client.componentes.BasisComponentes;
import br.gov.ibama.client.componentes.PopUpBasis;
import br.gov.ibama.client.constantes.ConstantesDS;
import br.gov.ibama.client.constantes.ConstantesFields;

import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.DSCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.HiddenItem;
import com.smartgwt.client.widgets.form.fields.PasswordItem;
import com.smartgwt.client.widgets.form.fields.TextItem;

public class VisaoPopupFuncionario extends PopUpBasis{

	public VisaoPopupFuncionario(String title) {
		super (title);
	}

	public VisaoPopupFuncionario (String title, int estado){
		super(title, estado);
	}
	
	protected List<ImgButton> getBotoes (){
		List<ImgButton> listaBotoes = new ArrayList<ImgButton>();
		listaBotoes.add(getBotaoSalvar());
		listaBotoes.add(getBotaoCancelar());
		return listaBotoes;
	}
	
	private ImgButton getBotaoSalvar(){
		ImgButton Salvar = BasisComponentes.criaImgButton("Salvar", "salvar_32x32.png");
		Salvar.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				
				if (validaCampos()) {
					if(getEstado() == PopUpBasis.ESTADO_EDITAR){
						
						FormItem login = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_LOGIN);
						Criteria criteria = new Criteria();
						criteria.addCriteria(ConstantesFields.FIELD_FUNCIONARIO_LOGIN, login.getValue().toString());
						DataSource.get(ConstantesDS.DS_FUNCIONARIO).fetchData(criteria, new DSCallback() {
							
							@Override
							public void execute(DSResponse response, Object rawData, DSRequest request) {
								if (!response.getDataAsRecordList().isEmpty() &&
										response.getDataAsRecordList().getLength() > 1) {
									SC.warn("A nome inserido no campo Login não está disponível! Por favor, escolha outro.");
								} else {
									
									FormItem cargo = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_CARGO);
									Criteria criteria = new Criteria();
									criteria.addCriteria(ConstantesFields.FIELD_FUNCIONARIO_CARGO, cargo.getValue().toString());
									DataSource.get(ConstantesDS.DS_CARGO).fetchData(criteria, new DSCallback() {
										
										@Override
										public void execute(DSResponse response, Object rawData, DSRequest request) {
											if (response.getDataAsRecordList().isEmpty()) {
												SC.warn("O cargo digitado não existe!");
											} else {
												
												FormItem cidade = getFormulario().getItem(ConstantesFields.FIELD_CIDADE_ID);
												Criteria criteria = new Criteria();
												criteria.addCriteria(ConstantesFields.FIELD_CIDADE_ID, cidade.getValue().toString());
												DataSource.get(ConstantesDS.DS_CIDADE).fetchData(criteria, new DSCallback() {
													
													@Override
													public void execute(DSResponse response, Object rawData, DSRequest request) {
														if (response.getDataAsRecordList().isEmpty()) {
															SC.warn("A cidade digitada não está cadastrada! Por favor, utilize o botão de seleção.");
														} else {
															Record record = formulario.getValuesAsRecord();
															DataSource.get(ConstantesDS.DS_ENDERECO).updateData(record,new DSCallback() {
																
																@Override
																public void execute(DSResponse response, Object rawData, DSRequest request) {
																	if (!response.getDataAsRecordList().isEmpty()) {
																		Record record = formulario.getValuesAsRecord();
																		DataSource.get(ConstantesDS.DS_FUNCIONARIO).updateData(record,new CallBackSalvarEditar());							
																	}
																	
																}
															});				
														}														
													}
												});							
											}
										}
									});											
								}											
							}
						});			
							
					} else if(getEstado() == PopUpBasis.ESTADO_SALVAR){
						FormItem cpf = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_CPF);
						Criteria criteria = new Criteria();
						criteria.addCriteria(ConstantesFields.FIELD_FUNCIONARIO_CPF, cpf.getValue().toString());
						DataSource.get(ConstantesDS.DS_FUNCIONARIO).fetchData(criteria, new DSCallback() {
							
							@Override
							public void execute(DSResponse response, Object rawData, DSRequest request) {
								
								if (!response.getDataAsRecordList().isEmpty()) {
									SC.warn("O valor inserido no campo CPF já existe!");
								} else {
									FormItem login = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_LOGIN);
									Criteria criteria = new Criteria();
									criteria.addCriteria(ConstantesFields.FIELD_FUNCIONARIO_LOGIN, login.getValue().toString());
									DataSource.get(ConstantesDS.DS_FUNCIONARIO).fetchData(criteria, new DSCallback() {
										
										@Override
										public void execute(DSResponse response, Object rawData, DSRequest request) {
											
											if (!response.getDataAsRecordList().isEmpty()) {
												SC.warn("A nome inserido no campo Login não está disponível! Por favor, escolha outro.");
											} else {						
												FormItem cargo = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_CARGO);
												Criteria criteria = new Criteria();
												criteria.addCriteria(ConstantesFields.FIELD_FUNCIONARIO_CARGO, cargo.getValue().toString());
												DataSource.get(ConstantesDS.DS_CARGO).fetchData(criteria, new DSCallback() {
													
													@Override
													public void execute(DSResponse response, Object rawData, DSRequest request) {
														if (response.getDataAsRecordList().isEmpty()) {
															SC.warn("O cargo digitado não existe!");
														} else {
															
															FormItem cidade = getFormulario().getItem(ConstantesFields.FIELD_CIDADE_ID);
															Criteria criteria = new Criteria();
															criteria.addCriteria(ConstantesFields.FIELD_CIDADE_ID, cidade.getValue().toString());
															DataSource.get(ConstantesDS.DS_CIDADE).fetchData(criteria, new DSCallback() {
																
																@Override
																public void execute(DSResponse response, Object rawData, DSRequest request) {
																	if (response.getDataAsRecordList().isEmpty()) {
																		SC.warn("A cidade digitada não está cadastrada! Por favor, utilize o botão de seleção.");
																	} else {
																		Record record = getFormulario().getValuesAsRecord();
																		DataSource.get(ConstantesDS.DS_ENDERECO).addData(record,new DSCallback() {
																			
																			@Override
																			public void execute(DSResponse response, Object rawData, DSRequest request) {
																				if (!response.getDataAsRecordList().isEmpty()) {
																					Record record = formulario.getValuesAsRecord();
																					String enderecoId = response.getDataAsRecordList().get(0).getAttribute(ConstantesFields.FIELD_ENDERECO_ID);
																					record.setAttribute(ConstantesFields.FIELD_ENDERECO_ID, enderecoId);
																					DataSource.get(ConstantesDS.DS_FUNCIONARIO).addData(record,new CallBackSalvarEditar());							
																				}
																			}
																		});		
																	}																	
																}
															});																	
														}
													}
												});														
											}											
										}
									});			
								}
							}
						});						
					}
				}
			}
		});
		return Salvar;
	}
	
	private ImgButton getBotaoCancelar(){
		ImgButton Cancelar = BasisComponentes.criaImgButton("Cancelar", "cancelar_32x32.png");
		Cancelar.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				destroy();
				
			}
		});
		return Cancelar;
	}
	
	public void criaFormulario(){
		preparaFormulario(ConstantesDS.DS_FUNCIONARIO, getListaCamposFormulario());
			}
	public FormItem[] getListaCamposFormulario(){
		return getCamposFormulario().toArray(new FormItem[getCamposFormulario().size()]);
	}
	
	private List<FormItem> getCamposFormulario(){
		List<FormItem> listaCampos = new ArrayList<FormItem>();
	
		TextItem cpf = BasisComponentes.criaTextItemPequeno(ConstantesFields.FIELD_FUNCIONARIO_CPF);
		cpf.setMask("###.###.###-##");
		if(getEstado() == PopUpBasis.ESTADO_EDITAR) {
			cpf.setCanEdit(false);
		}
		listaCampos.add(cpf);
		
		TextItem login = BasisComponentes.criaTextItemRequeridoPequeno(ConstantesFields.FIELD_FUNCIONARIO_LOGIN, "Login");
		listaCampos.add(login);
		
		PasswordItem senha = new PasswordItem(ConstantesFields.FIELD_FUNCIONARIO_SENHA, "Senha");
		senha.setRequired(true);
		senha.setWidth(220);
		listaCampos.add(senha);		
		
		TextItem cargo = BasisComponentes.criaComboboxObrigatorioGrande(ConstantesFields.FIELD_FUNCIONARIO_CARGO, "Cargo");
		cargo.setOptionDataSource(DataSource.get(ConstantesDS.DS_CARGO));
		cargo.setDisplayField(ConstantesFields.FIELD_CARGO_DESCRICAO);
		cargo.setValueField(ConstantesFields.FIELD_CARGO_ID);
		listaCampos.add(cargo);
		
		TextItem nome = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_FUNCIONARIO_NOME, "Nome");
		listaCampos.add(nome);

		TextItem rg = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_FUNCIONARIO_RG, "RG");
		listaCampos.add(rg);

		TextItem matricula = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_FUNCIONARIO_MATRICULA, "Matrícula");
		listaCampos.add(matricula);
		
		HiddenItem idEndereco = new HiddenItem(ConstantesFields.FIELD_ENDERECO_ID);
		listaCampos.add(idEndereco);
		
		TextItem logradouro = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_ENDERECO_LOGRADOURO, "Logradouro");
		listaCampos.add(logradouro);
		
		TextItem numero = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_ENDERECO_NUMERO, "Número");
		listaCampos.add(numero);

		TextItem bairro = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_ENDERECO_BAIRRO, "Bairro");
		listaCampos.add(bairro);
		
		TextItem cidade = BasisComponentes.criaComboboxObrigatorioGrande(ConstantesFields.FIELD_ENDERECO_CIDADE_ID, "Cidade");
		cidade.setOptionDataSource(DataSource.get(ConstantesDS.DS_CIDADE));
		cidade.setDisplayField(ConstantesFields.FIELD_CIDADE_NOME);
		cidade.setValueField(ConstantesFields.FIELD_CIDADE_ID);
		listaCampos.add(cidade);
		
		TextItem cep = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_ENDERECO_CEP, "CEP");
		cep.setMask("##.###-###");
		listaCampos.add(cep);
		
		TextItem pontoReferencia = BasisComponentes.criaTextItemRequeridoGrande(ConstantesFields.FIELD_ENDERECO_PONTO_REFERENCIA, 
				"Ponto de Referência");
		listaCampos.add(pontoReferencia);
		
		return listaCampos;
		
		
	}
	
	private boolean validaCampos() {
		FormItem cpf = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_CPF);
		FormItem login = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_LOGIN);
		FormItem senha = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_SENHA);
		FormItem cargo = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_CARGO);
		FormItem nome = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_NOME);
		FormItem rg = getFormulario().getItem(ConstantesFields.FIELD_FUNCIONARIO_RG);
		FormItem logradouro = getFormulario().getItem(ConstantesFields.FIELD_ENDERECO_LOGRADOURO);
		FormItem cidade = getFormulario().getItem(ConstantesFields.FIELD_ENDERECO_CIDADE_ID);
		
		// Verifica preenchimento dos campos obrigatórios
		if (isVazio(cpf) || isVazio(login) || isVazio(senha) || isVazio(cargo) 
				|| isVazio(nome) || isVazio(rg) || isVazio(logradouro) || isVazio(cidade)) {
			SC.warn("Há campos obrigatórios não preenchidos.");
			return false;
		}
		
		// Valida o CPF	
		if(getEstado() == PopUpBasis.ESTADO_SALVAR) {
			if (!validaCPF(cpf.getValue().toString())) {
				SC.warn("CPF inválido!");
				return false;
			}
		}

		return true;
	}

	private boolean validaCPF(String cpf) {
	   String strCpf = cpf;
        if (strCpf.equals("")) {
            return false;
        } 
        
        if (strCpf.length() < 11) {
        	return false;
        }
        
        int d1, d2;
        int digito1, digito2, resto;
        int digitoCPF;
        String nDigResult;

        d1 = d2 = 0;
        digito1 = digito2 = resto = 0;

        for (int nCount = 1; nCount < strCpf.length() - 1; nCount++) {
            digitoCPF = Integer.valueOf(strCpf.substring(nCount - 1, nCount)).intValue();

            //multiplique a ultima casa por 2 a seguinte por 3 a seguinte por 4 e assim por diante.  
            d1 = d1 + (11 - nCount) * digitoCPF;

            //para o segundo digito repita o procedimento incluindo o primeiro digito calculado no passo anterior.  
            d2 = d2 + (12 - nCount) * digitoCPF;
        }

        //Primeiro resto da divisão por 11.  
        resto = (d1 % 11);

        //Se o resultado for 0 ou 1 o digito é 0 caso contrário o digito é 11 menos o resultado anterior.  
        if (resto < 2) {
            digito1 = 0;
        } else {
            digito1 = 11 - resto;
        }

        d2 += 2 * digito1;

        //Segundo resto da divisão por 11.  
        resto = (d2 % 11);

        //Se o resultado for 0 ou 1 o digito é 0 caso contrário o digito é 11 menos o resultado anterior.  
        if (resto < 2) {
            digito2 = 0;
        } else {
            digito2 = 11 - resto;
        }

        //Digito verificador do CPF que está sendo validado.  
        String nDigVerific = strCpf.substring(strCpf.length() - 2, strCpf.length());

        //Concatenando o primeiro resto com o segundo.  
        nDigResult = String.valueOf(digito1) + String.valueOf(digito2);

        //comparar o digito verificador do cpf com o primeiro resto + o segundo resto.  
        return nDigVerific.equals(nDigResult);		
	}
	
	private final class CallBackSalvarEditar implements DSCallback {
		@Override
		public void execute(DSResponse response, Object rawData, DSRequest request) {
			if (RPCResponse.STATUS_SUCCESS == response.getStatus()) {
				if(getEstado() == PopUpBasis.ESTADO_SALVAR){
					SC.say("Incluído com sucesso");
					destroy();
				}
				else if(getEstado() == PopUpBasis.ESTADO_EDITAR){
					SC.say("Alterado com sucesso");
					destroy();
				}				
			} else if (RPCResponse.STATUS_VALIDATION_ERROR == response.getStatus()) {
				formulario.setErrors(response.getErrors(), true);
				SC.say("Existem erros de validação, por favor verificar os dados informados.");
			} else if (RPCResponse.STATUS_FAILURE == response.getStatus()) {
				SC.say("Falha ao executar a operação.");
			}
		}
	}

}
